package controller

import (
	"dsc-server/domain/dto"
	"dsc-server/domain/req"
	model2 "dsc-server/pkg/model"
	service2 "dsc-server/pkg/service"
	"fmt"
	"github.com/bytedance/sonic"
	"github.com/liangboceo/yuanboot/abstractions/xlog"
	"github.com/liangboceo/yuanboot/web/actionresult"
	"github.com/liangboceo/yuanboot/web/context"
	"github.com/liangboceo/yuanboot/web/mvc"
	"strconv"
)

type CacheController struct {
	mvc.ApiController `doc:"前台缓存"`
	cache             *service2.CacheService
	db                *service2.DbService
	log               xlog.ILogger
}

func NewCacheController(cacheService *service2.CacheService, dbService *service2.DbService) *CacheController {
	return &CacheController{cache: cacheService, db: dbService, log: xlog.GetXLogger("CacheController")}
}

// GetFrontCache 获取前台服务缓存
func (controller *CacheController) GetFrontCache(req *req.CacheReq) actionresult.IActionResult {
	var res []byte
	if req.ServerName == "" || req.KeyName == "" {
		res, _ = sonic.Marshal(dto.FailureMessage("", "服务名/缓存md5Key不能为空"))
		return actionresult.Data{
			ContentType: "application/json; charset=utf-8",
			Data:        res,
		}
	}
	value := controller.cache.GetCache(req)
	res, _ = sonic.Marshal(dto.Success(value))
	return actionresult.Data{
		ContentType: "application/json; charset=utf-8",
		Data:        res,
	}
}

// SetFrontCache  设置缓存前台服务
func (controller *CacheController) SetFrontCache(req *req.CacheSetReq) actionresult.IActionResult {
	var res []byte
	if req.ServerName == "" || req.KeyName == "" {
		res, _ = sonic.Marshal(dto.FailureMessage("", "服务名/缓存md5Key不能为空"))
		return actionresult.Data{
			ContentType: "application/json; charset=utf-8",
			Data:        res,
		}
	}
	key := fmt.Sprintf("SetFrontCache:%s:%s", req.ServerName, req.KeyName)
	defer controller.cache.Unlock(key)
	if !controller.cache.Lock(key, 60) {
		res, _ = sonic.Marshal(dto.FailureMessage("", "请勿重复设置缓存"))
		return actionresult.Data{
			ContentType: "application/json; charset=utf-8",
			Data:        res,
		}
	}
	value := controller.cache.SetCache(req)
	if !value {
		res, _ = sonic.Marshal(dto.Failure(value))
	} else {
		res, _ = sonic.Marshal(dto.Success(value))
	}
	return actionresult.Data{
		ContentType: "application/json; charset=utf-8",
		Data:        res,
	}
}

// SetCacheRule 设置前台缓存规则
func (controller *CacheController) SetCacheRule(req *req.CacheSetRuleReq, ctx *context.HttpContext) actionresult.IActionResult {
	var res []byte
	_ = sonic.Unmarshal(ctx.Input.GetBody(), req)
	str, _ := sonic.Marshal(req)
	controller.log.Info("SetCacheRule.req:%s", str)
	if req.ServerName == "" || req.KeyName == "" || req.Rule == "" {
		res, _ = sonic.Marshal(dto.FailureMessage("", "服务名/缓存md5Key/规则不能为空"))
		return actionresult.Data{
			ContentType: "application/json; charset=utf-8",
			Data:        res,
		}
	}
	cacheSetting := model2.CacheSetting{
		ServerName: req.ServerName,
		KeyName:    req.KeyName,
		Rule:       req.Rule,
		Url:        req.Url,
		Expire:     req.Expire,
		BaseModel: model2.BaseModel{
			ID:            req.ID,
			CreateOrgCode: strconv.Itoa(req.CreateOrgCode),
		},
		CommonModel: model2.CommonModel{
			IsDeleted:  req.IsDeleted,
			CreateBy:   req.CreateBy,
			CreateTime: req.CreateTime,
			UpdateBy:   req.UpdateBy,
			UpdateTime: req.UpdateTime,
			CreateName: req.CreateName,
			UpdateName: req.UpdateName,
		},
	}
	key := fmt.Sprintf("SetCacheRule:%s:%s", req.ServerName, req.KeyName)
	defer controller.cache.Unlock(key)
	if !controller.cache.Lock(key, 60) {
		res, _ = sonic.Marshal(dto.FailureMessage("", "请勿重复设置缓存规则"))
		return actionresult.Data{
			ContentType: "application/json; charset=utf-8",
			Data:        res,
		}
	}
	/*保存规则*/
	err := controller.db.SaveCacheSetting(&cacheSetting)
	controller.log.Info("SetCacheRule.req.error:%s", err)
	if err != nil {
		res, _ = sonic.Marshal(dto.Failure(cacheSetting))
	} else {
		res, _ = sonic.Marshal(dto.Success(cacheSetting))
	}
	return actionresult.Data{ContentType: "application/json; charset=utf-8",
		Data: res}
}

// GetCacheRule 分页获取设置前台缓存规则
func (controller *CacheController) GetCacheRule(req *req.CacheGetRuleReq, ctx *context.HttpContext) actionresult.IActionResult {
	var res []byte
	_ = sonic.Unmarshal(ctx.Input.GetBody(), req)
	str, _ := sonic.Marshal(req)
	controller.log.Info("GetCacheRule.req:%s", str)
	data, err := controller.db.GetCacheSetting(req)
	if err != nil {
		res, _ = sonic.Marshal(dto.Failure(data))
	} else {
		res, _ = sonic.Marshal(dto.Success(data))
	}
	return actionresult.Data{ContentType: "application/json; charset=utf-8",
		Data: res}
}

// GetCacheView 分页获取设置前台缓存访问
func (controller *CacheController) GetCacheView(req *req.CacheGetViewReq, ctx *context.HttpContext) actionresult.IActionResult {
	var res []byte
	_ = sonic.Unmarshal(ctx.Input.GetBody(), req)
	str, _ := sonic.Marshal(req)
	controller.log.Info("GetCacheView.req:%s", str)
	data, err := controller.db.GetCacheView(req)
	if err != nil {
		res, _ = sonic.Marshal(dto.Failure(data))
	} else {
		res, _ = sonic.Marshal(dto.Success(data))
	}
	return actionresult.Data{ContentType: "application/json; charset=utf-8",
		Data: res}
}

// Info 获取redis详情
func (controller *CacheController) Info() actionresult.IActionResult {
	var res []byte
	data, err := controller.cache.Info()
	if err != nil {
		res, _ = sonic.Marshal(dto.Failure(data))
	} else {
		res, _ = sonic.Marshal(dto.Success(data))
	}
	return actionresult.Data{ContentType: "application/json; charset=utf-8",
		Data: res}
}

// GetKeys 获取keys
func (controller *CacheController) GetKeys(keysReq *req.KeysReq, ctx *context.HttpContext) actionresult.IActionResult {
	var res []byte
	_ = sonic.Unmarshal(ctx.Input.GetBody(), keysReq)
	str, _ := sonic.Marshal(keysReq)
	controller.log.Info("GetKeys.req:%s", str)
	data, err := controller.cache.GetKeys(keysReq)
	if err != nil {
		res, _ = sonic.Marshal(dto.Failure(data))
	} else {
		res, _ = sonic.Marshal(dto.Success(data))
	}
	return actionresult.Data{ContentType: "application/json; charset=utf-8",
		Data: res}
}

// GetKeyInfo 获取keys
func (controller *CacheController) GetKeyInfo(keyInfoReq *req.KeyInfoReq, ctx *context.HttpContext) actionresult.IActionResult {
	var res []byte
	_ = sonic.Unmarshal(ctx.Input.GetBody(), keyInfoReq)
	str, _ := sonic.Marshal(keyInfoReq)
	controller.log.Info("GetKeyInfo.req:%s", str)
	data, err := controller.cache.GetKeyInfo(keyInfoReq)
	if err != nil {
		res, _ = sonic.Marshal(dto.Failure(data))
	} else {
		res, _ = sonic.Marshal(dto.Success(data))
	}
	return actionresult.Data{ContentType: "application/json; charset=utf-8",
		Data: res}
}

// BatchDeleteKeys 批量刪除keys
func (controller *CacheController) BatchDeleteKeys(keyDeleteReq *req.KeyDeleteReq, ctx *context.HttpContext) actionresult.IActionResult {
	var res []byte
	_ = sonic.Unmarshal(ctx.Input.GetBody(), keyDeleteReq)
	str, _ := sonic.Marshal(keyDeleteReq)
	controller.log.Info("BatchDeleteKeys.req:%s", str)
	flag := controller.cache.BatchDeleteKeys(keyDeleteReq)
	res, _ = sonic.Marshal(dto.Success(flag))
	return actionresult.Data{ContentType: "application/json; charset=utf-8",
		Data: res}
}

// SetKeyValue 设置key值
func (controller *CacheController) SetKeyValue(setKeysReq *req.SetKeysReq, ctx *context.HttpContext) actionresult.IActionResult {
	var res []byte
	_ = sonic.Unmarshal(ctx.Input.GetBody(), setKeysReq)
	str, _ := sonic.Marshal(setKeysReq)
	controller.log.Info("SetKeyValue.req:%s", str)
	data, err := controller.cache.SetKeyValue(setKeysReq)
	if err != nil {
		res, _ = sonic.Marshal(dto.Failure(data))
	} else {
		res, _ = sonic.Marshal(dto.Success(data))
	}
	return actionresult.Data{ContentType: "application/json; charset=utf-8",
		Data: res}
}
